package com.example.riqrtest;

import java.io.File;

import com.example.maps.HelloMapsAct;
import com.example.qr.QRDecoder;
import com.example.riqrtest.HandleNotifyAct;

import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.app.NotificationCompat;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.TextView;

public class MainAct extends Activity {

	/**
	 * The name of the temporary image file containing a QR code, captured from the camera.
	 */
	private static final String TMP_IMG_NAME = "qrcode.png";
	
	/**
	 * An integer code for calling the camera app via intent.
	 */
	private static final int QR_PIC_REQUEST = 217893458;
	
	
	
	
	
	/**
	 * The key string responsible for saving and retrieving the file path where the temporary image will be stored.
	 */
	private static final String SAVE_CAM_IMG = "SAVE_CAM_IMG";
	/**
	 * An uniform resource index containing the absolute file path of the temporary image on the phone.
	 * 
	 * This variable is a hack, necessary to deal with the built-in camera app returning no data to
	 * onActivityResult(). 
	 * Instead, the location of the saved picture is stored in this variable.
	 */
	private Uri camTmpImg; 
	
	
	
	
	
	/**
	 * This is a unique ID that is associated with a notification object, changed every time a new notification is generated.
	 */
	private static int NOTIFICATION_ID = 0;

	
	
	
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main_act);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main_act, menu);
		return true;
	}
	/**
	 * Save any states from memory onto the device's permanent storage.
	 * 
	 * Current usage: Preserve temporary image file path, which is used by the camera app to store
	 * 							the captured image, to be decoded by the app.
	 */
	@Override
	protected void onSaveInstanceState(Bundle savedInstanceState) {
		super.onSaveInstanceState(savedInstanceState);
		if (camTmpImg != null) {
			savedInstanceState.putParcelable(SAVE_CAM_IMG, camTmpImg);
		}
	}
	@Override
	protected void onRestoreInstanceState(Bundle savedInstanceState) {
		super.onRestoreInstanceState(savedInstanceState);
		savedInstanceState.getParcelable(SAVE_CAM_IMG);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		//The app has requested a camera-using application to take a picture.
		//If the app took an image, try to decode a QR code from the image
		//Delete the image and the temporarily created directory after decoding it.
		if (requestCode == QR_PIC_REQUEST) {  
			if (resultCode == RESULT_OK) {
				if (camTmpImg == null) {
					return;
				}
				TextView decodedRes = (TextView) findViewById(R.id.resultText);
				decodedRes.setText(QRDecoder.decodeImage(camTmpImg.getPath()));
				
				File tmpImgDir = new File(camTmpImg.getPath());
				tmpImgDir.delete();
				tmpImgDir = new File(tmpImgDir.getParent());
				if (tmpImgDir != null) {
					tmpImgDir.delete();
				}
			}
			else if (resultCode == RESULT_CANCELED){
				TextView textView = (TextView) findViewById(R.id.resultText);
				textView.setText("Took no picture");
			}
		}  
	} 

	/**
	 * Event response method when the QR Code button is clicked.
	 * 
	 * This method tries to create the temporary directory necessary to store the image to be decoded for QR code.
	 * If successful, it will then launch the native camera app to take a picture.
	 * @param view
	 */
	public void launchCamera(View view) {

		String storageState = Environment.getExternalStorageState();
		if (!storageState.equals(Environment.MEDIA_MOUNTED)) {
			//If the external (public, app-sharable) storage space is unavailable, one shouldn't use the camera
			  AlertDialog.Builder dialog = new AlertDialog.Builder(getApplicationContext());
			  dialog.setTitle("Cannot Capture QR Code");
			  dialog.setMessage("Please insert an external storage device before scanning for QR code.");
			  dialog.show();
			  return;
		}
		
		String dirName = getApplication().getPackageName() + File.separator;
		File checkDir = new File(Environment.getExternalStorageDirectory(), getApplication().getPackageName());
		if (!checkDir.exists()) {
			boolean mkDirRes = checkDir.mkdir();
			if (!mkDirRes) {
				//Could not create the cache directory, return.
				AlertDialog.Builder dialog = new AlertDialog.Builder(getApplicationContext());
				dialog.setTitle("Cannot Capture QR Code");
				dialog.setMessage("There is an error trying to establish the cache directory.");
				dialog.show();
				return;
			}
		}
		
		//We tell the camera app to save the captured image to the cache.
		File tmpFileFullPath = new File(Environment.getExternalStorageDirectory(), dirName + TMP_IMG_NAME);
		camTmpImg = Uri.fromFile(tmpFileFullPath);
		
		//We intend for the camera app to capture an image with the image being temporarily written to the cache.
		Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		intent.putExtra(MediaStore.EXTRA_OUTPUT, camTmpImg);
		startActivityForResult(intent, QR_PIC_REQUEST);
	}
	
	/**
	 * Event response method for the button Make Notification. Generates a notification every time it is clicked.
	 * @param view
	 */
	public void createNotification(View view) {
		Notification notification = buildNotification(NOTIFICATION_ID);
		NotificationManager notificationManager = (NotificationManager) 
				  getSystemService(NOTIFICATION_SERVICE); 
		//Increment the ID after broadcasting the notification so that each button press generates a new notification.
		notificationManager.notify(NOTIFICATION_ID++, notification);
	}
	
	public void viewMap(View view) {
		Intent intent = new Intent(this, HelloMapsAct.class);
		startActivity(intent);
	}
	
	/**
	 * This method contains sample code for building a basic, text-only notification object that is compatible for
	 * Android API version 7-16. This code requires Android Support Library v4.
	 * @param notify_id The unique ID of the notification.
	 * @return The built notification object.
	 */
	private Notification buildNotification(int notify_id) {
		
		int icon = R.drawable.ic_notify;        // icon from resources
		CharSequence tickerText = "Hello";              // text to display on status bar.
		long when = System.currentTimeMillis();         // Time of notification
		Context context = getApplicationContext();      // Application's context
		String contentTitle = "My notification";  // message title
		String contentText = "Hello World!";      // message text
		
		//Specify the activity that will come into view when a notification is clicked.
		Intent notificationIntent = new Intent(context, HandleNotifyAct.class);
		//Put relevant information, such as the title and message into the notification
		notificationIntent.putExtra(HandleNotifyAct.INTENT_TITLE_KEY, contentTitle);
		notificationIntent.putExtra(HandleNotifyAct.INTENT_CONTENT_KEY, contentText);
		notificationIntent.putExtra(HandleNotifyAct.INTENT_ID_KEY, notify_id); 
		notificationIntent.putExtra(HandleNotifyAct.INTENT_TIME_KEY, when);
		
		PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
		
		//Build the notification using compatibility library.
		NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
		notificationBuilder = notificationBuilder.setContentIntent(contentIntent); //Launch the activity specified by the intent when clicked.
		notificationBuilder = notificationBuilder.setTicker(tickerText);
		notificationBuilder = notificationBuilder.setWhen(when); //Set the time that the notification occurred
		notificationBuilder = notificationBuilder.setAutoCancel(true); //Automatically delete this notification after being clicked
		notificationBuilder = notificationBuilder.setContentTitle(contentTitle); //Set the notification's title
		notificationBuilder = notificationBuilder.setContentText(contentText); //Set the text/message
		notificationBuilder = notificationBuilder.setSmallIcon(icon); //Use a custom icon
		Notification notification = notificationBuilder.build(); //Build it
		return notification;
	}

}
